home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 425_01 / tar / streamer.c < prev    next >
Text File  |  1980-07-23  |  20KB  |  710 lines

  1. #ifdef __TURBOC__
  2. #include <dos.h>
  3. #include <errno.h>
  4. #include <string.h>
  5.  
  6. #include "qic02.h"
  7.  
  8. /*****************************************************\
  9.  * Quarter-Inch-Cartridge no. 02 standart error list *
  10. \*****************************************************/
  11.  
  12. static char *err[] = {
  13.    "udefined error",
  14.    "Ok",
  15.    "reset in progress",    /* hardware status */
  16.    "end of recorded media",
  17.    "bus parity error",
  18.    "beginning of media",
  19.    "marginal block detected",
  20.    "no data detected",
  21.    "illegal command",
  22.    "timeout expired",    /* software flag */
  23.    "file mark detected",
  24.    "block not located",
  25.    "unrecoverable data error",
  26.    "end of medium",
  27.    "write protected",
  28.    "device fault",
  29.    "cartridge not in place",
  30.    "drive busy",    /* software error codes */
  31.    "device not opened",
  32.    "device already opened",
  33. };
  34.  
  35. char **qic02_errlist = err+1;
  36. int  qic02_nerr = sizeof(err)/sizeof(*err) - 1;
  37.  
  38. /****************************************************\
  39.  * Quarter-Inch-Cartridge no. 02 standart interface *
  40. \****************************************************/
  41.  
  42. extern unsigned long timer(void);
  43. extern unsigned long suspend_value(unsigned);
  44. extern void suspend(unsigned long);
  45. extern void interrupt cthandle();
  46. extern long ptr2abs(void far *);
  47.  
  48. static unsigned long wait03us, wait25ms;
  49.  
  50. #define CT_OPENED  0x08
  51. #define CT_CHECKED 0x10
  52. #define CT_EVENT   0x20
  53. #define CT_PROTECT 0x40
  54.  
  55. #define MASK_BOARD 0x7f
  56. #define SKIP_RESET 0x80
  57.  
  58. /* Calculate number of ticks by 300 ms units */
  59. #define TIMEOUT(x) (int)((3*119318L*(x) + 65535L) / 65536L)
  60. #define MINTIME    TIMEOUT(1)
  61. #define MAXTIME    TIMEOUT(1000)
  62. #define WAITIME    TIMEOUT(10)
  63. #define HALT_CPU   /*__emit__(0xf4)*/
  64. #define dim(x)     (sizeof(x)/sizeof(*(x)))
  65. #define NTRY       3
  66.  
  67. #define Q2_READBIT 0x80
  68. #define DMA_WRDEV  8
  69. #define DMA_RDDEV  4
  70.  
  71. #define ALIASLEN 8
  72.  
  73. struct _ct_define {
  74.    char (*aliases)[ALIASLEN]; int naliases;
  75.    WORD valid_base, off_control, off_data, off_launch, off_clear;
  76.    BYTE mask_reset, val_reset;
  77.    BYTE mask_event, not_event;
  78.    BYTE mask_ready, not_ready;
  79.    BYTE mask_excep, not_excep;
  80.    BYTE mask_dma,   done_dma;
  81.    BYTE mask_xfer,  no_xfer;
  82.  
  83.    BYTE set_reset, set_request, set_online;
  84.    BYTE ienable, denable, dma_valid, rundma[8];
  85. };
  86.  
  87. static char archivenames[][ALIASLEN]={
  88.    "archive","fastape", "sc499", "sc-499", "sc402", "sc-402",
  89. };
  90. static char everexnames [][ALIASLEN]={
  91.    "everex", "sc409a", "sc-409a",
  92. };
  93. static char wangteknames[][ALIASLEN]={
  94.    "wangtek",
  95. };
  96.  
  97.  
  98. struct _ct_define sc499 = {
  99.    archivenames, dim(archivenames),
  100.    0x3f8, 1, 0, 2, 3,
  101.    0xf0, 0x50,
  102.    0x80, 0x80,
  103.    0x40, 0x40,
  104.    0x20, 0x20,
  105.    0x10, 0x10,
  106.    0x08, 0x00,
  107.  
  108.    0x80, 0x40, 0,
  109.    0x20, 0x10, 0x0A, { 0, 0, 0, 0, 0, 0, 0, 0 },
  110. };
  111.  
  112. struct _ct_define sc409a = {
  113.    everexnames, dim(everexnames),
  114.    0x3ff, 0, 1, UNUSED, UNUSED,
  115.    7,    5,
  116.    0,    0,
  117.    1,    1,
  118.    2,    2,
  119.    0,    0,
  120.    4,    4,
  121.  
  122.    2, 4, 1,
  123.    0x40, 0, 0x0E, { 0, 8, 8, 8, 0, 0, 0, 0 },
  124. };
  125.  
  126. struct _ct_define wangtek = {
  127.    wangteknames, dim(wangteknames),
  128.    0x3ff, 0, 1, UNUSED, UNUSED,
  129.    7,    5,
  130.    0,    0,
  131.    1,    1,
  132.    2,    2,
  133.    0,    0,
  134.    4,    4,
  135.  
  136.    2, 4, 1,
  137.    0, 0, 0x0E, { 0, 8, 8, 16, 0, 0, 0, 0 },
  138. };
  139.  
  140. struct _ct_define *ct_list[] = {
  141.    &sc499, &sc409a, &wangtek
  142. };
  143.  
  144. struct _ct_pic {
  145.    WORD base;
  146.    BYTE ack, chain;
  147.    void interrupt (*old)();
  148.    int number; BYTE save;
  149. } ct_pic;
  150.  
  151. struct _ct_dma {
  152.    WORD page, address, counter;
  153.    WORD mask, mode, clear;
  154.    BYTE read, write;
  155. } ct_dma;
  156.  
  157. BYTE lastcmd = UNUSED;
  158. WORD ct_error;
  159. volatile struct _ct_psw {
  160.    BYTE flags;
  161.    BYTE input;
  162. } ct_psw;
  163.  
  164. struct _ct_control {
  165.    WORD control, data, launch, clear;
  166.    BYTE mask_reset, val_reset;
  167.    BYTE mask_event, not_event;
  168.    BYTE mask_ready, not_ready;
  169.    BYTE mask_excep, not_excep;
  170.    BYTE mask_state, inv_state;
  171.    BYTE mask_xfer,  no_xfer;
  172.    BYTE mask_dma,   done_dma;
  173.  
  174.    BYTE do_reset, request, online;
  175.    BYTE int_enable, done_enable, dma_enable;
  176. } ct_set;
  177.  
  178. static WORD ct_error;
  179. static BYTE statbuf[6];
  180.  
  181. #define ctlport    (ct_set.control)
  182. #define cmdport    (ct_set.data)
  183. #define statport   (ct_set.control)
  184. #define dataport   (ct_set.data)
  185.  
  186. #define DMAGO      (ct_set.launch)
  187. #define DMACL      (ct_set.clear)
  188.  
  189. #define MASK_RESET ct_set.mask_reset
  190. #define VAL_RESET  ct_set.val_reset
  191. #define MASK_READY ct_set.mask_ready
  192. #define NOT_READY  ct_set.not_ready
  193. #define MASK_EXCEP ct_set.mask_excep
  194. #define NOT_EXCEP  ct_set.not_excep
  195. #define MASK_STATE ct_set.mask_state
  196. #define INV_STATE  ct_set.inv_state
  197. #define DIRC       ct_set.mask_xfer
  198. #define XOFF       ct_set.no_xfer
  199. #define ON         ct_set.online
  200. #define REQ        ct_set.request
  201. #define RESET      ct_set.do_reset
  202. #define EI         ct_set.int_enable
  203. #define ED         ct_set.done_enable
  204. #define DMA        ct_set.dma_enable
  205. #define INP        ct_psw.input
  206. #define DMA_MAIN   ct_dma.mask
  207.  
  208. #define WAIT_READY(t)\
  209.     for ((t)=timer(); ((INP=inportb(statport))&MASK_READY)==NOT_READY;)\
  210.         { if (timer()-(t) > MINTIME) goto error; }
  211. #define WAIT_BUSY(t)\
  212.     for ((t)=timer(); ((INP=inportb(statport))&MASK_READY)!=NOT_READY;)\
  213.         { if (timer()-(t) > MINTIME) goto error; }
  214.  
  215. static int ct_iobyte(int c, unsigned char *p, unsigned length, unsigned tout)
  216. {
  217.    register i;
  218.    register long t, t0;
  219. #if 0
  220.    /* read-only now */ if (!(c & Q2_READBIT)) goto error;
  221. #endif
  222.    ct_psw.flags &= ~CT_CHECKED;
  223.    outportb(cmdport, lastcmd=c);
  224.    outportb(ctlport, REQ);
  225.    WAIT_READY(t);
  226.    outportb(ctlport, ON); /* Clear request */
  227.    WAIT_BUSY(t);
  228.  
  229.    t0 = timer();
  230.    i = c & Q2_READBIT ? XOFF : XOFF^DIRC;
  231.    while (((INP=inportb(statport)) & DIRC)==XOFF) {
  232.       if (timer()-t0 > tout) goto error;
  233.    }
  234.    for (i=0; i<length; i++) {
  235.       WAIT_READY(t);
  236.       if (c & Q2_READBIT) {
  237.          p[i] = inportb(dataport);
  238.       } else {
  239.          outportb(dataport, p[i]);
  240.       }
  241.       outportb(ctlport, REQ);
  242.       suspend(wait03us);
  243.       WAIT_BUSY(t);
  244.       outportb(ctlport, ON);
  245.    }
  246.    return i;
  247. error:
  248.    ct_error = Q2E_DEAD;
  249.    ct_psw.flags |= CT_CHECKED;
  250.    errno = EFAULT;
  251.    return -1;
  252. }
  253.  
  254. static int ct_test(void)
  255. {
  256.    register n;
  257.    register long t;
  258.  
  259.    for (t=timer(); ((INP=inportb(statport))&MASK_STATE)==INV_STATE;) {
  260.       if (timer()-t > MINTIME) {
  261.          ct_error = Q2E_BUSY; goto end;
  262.       }
  263.       HALT_CPU;
  264.    }
  265.    for (n=NTRY; n; n--) {
  266.       if (ct_iobyte(Q2_RDSTAT, statbuf, 6, TIMEOUT(10)) == 6) {
  267.          ct_error = (statbuf[0] & Q2_ERRFLAG) ?
  268.             (statbuf[0] & Q2_ERRMASK) << 8 : 0;
  269.          if (statbuf[1] & Q2_ERRFLAG) ct_error |= statbuf[1] & Q2_ERRMASK;
  270.          break;
  271.       }
  272.    }
  273. end:
  274.    ct_psw.flags |= CT_CHECKED;
  275.    return ct_error;
  276. }
  277.  
  278. static int ct_wait(BYTE mask, BYTE val, unsigned long t0, unsigned tout)
  279. {
  280.    while (((INP=inportb(statport)) & mask) == val) {
  281.       if ((INP & MASK_EXCEP) != NOT_EXCEP) return ct_test();
  282.       if (timer()-t0 > tout) {
  283.          ct_psw.flags |= CT_CHECKED;
  284.          return ct_error = (INP&MASK_READY)==NOT_READY ? Q2E_BUSY : Q2E_DEAD;
  285.       }
  286.       HALT_CPU;
  287.    }
  288.    return 0;
  289. }
  290.  
  291. static int ct_reset(void)
  292. {
  293.    register long t;
  294.  
  295.    outportb(ctlport, ct_set.do_reset);
  296.    suspend(wait25ms);
  297.    outportb(DMACL != UNUSED ? DMACL : ctlport, ON);
  298.    t = timer();
  299.    while ((((INP=inportb(statport)) & MASK_RESET) != VAL_RESET)) {
  300.       if (timer()-t > MINTIME) goto error; HALT_CPU;
  301.    }
  302.    while (!(ct_test() & Q2E_POR)) {
  303.       if (timer()-t > MAXTIME) goto error; HALT_CPU;
  304.    }
  305.    while (ct_test() & Q2E_POR) {
  306.       if (timer()-t > MAXTIME) goto error; HALT_CPU;
  307.    }
  308.    while ((INP=inportb(statport) & MASK_STATE) == INV_STATE) {
  309.       if (timer()-t > MAXTIME) goto error; HALT_CPU;
  310.    }
  311.    return 0;
  312. error:
  313.    return -1;
  314. }
  315.  
  316. int ct_errbit(register unsigned m)
  317. {
  318.    register n = 0;
  319.  
  320.    if (m) {
  321.       if      (m & Q2E_DEAD) m &= Q2E_DEAD;
  322.       else if (m & Q2E_HARD) m &= Q2E_HARD;
  323.       for (n=16; n && !(m & 0x8000); --n, m<<=1);
  324.    }
  325.